package com.lora.service.resolver;

import com.google.common.base.Strings;
import com.lora.dto.EquipmentDto;
import com.lora.entity.Temperaturehumidity;
import com.lora.service.NodeDataResolver;
import com.lora.service.TemperaturehumidityService;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;

import javax.annotation.Resource;
import java.math.BigDecimal;

/**
 * 温度采集器节点上报数据解析器
 */
@Service("temperatureCollectorNodeDataResolver")
public class TemperaturehumidityResolver implements NodeDataResolver<Temperaturehumidity> {

    @Resource
    private TemperaturehumidityService temperaturehumidityService;

    /**
     * 占用5个字节。第1、2字节表示温度值(16位有符号整形)，高字节在前，把1、2字节组合转为10进制再除以100得到温度值(单位℃)；
     * 第3、4字节表示湿度值(16位无符号整形)，高字节在前，把3、4字节组合转为10进制再除以100得到湿度值(单位%)；第5个字节为电压值，
     * 转换为10进制再除以10得到实际电压(单位V)。电压值转为二进制最高位为0表示电压正常，为1表示电压低，
     * 低7位表示电压值，实际值需除以10，如0x21表示3.3V，电压正常，0x9F表示3.1V，电压低。
     *
     * 示例1：温湿度节点上报的数据为base64编码的数据 CEgYsCQ= ，解码并转换成16进制。转换后的五个字节分别是 08 48 18 b0 24，
     * 把前两个字节0848的二进制(0000100001001000)最高位为0即为正值转成10进制是2120，除以100即为温度21.2度，18b0转成10进制是6320，
     * 除以100即为湿度63.2%，24为电压转成10进制是3.6V。
     *
     * 示例2: 温湿度节点上报的数据为base64编码的数据/Wwm8iE= ，解码并转为16进制。转换后的五个字节分别是fd 6c 26 f2 21 ，
     * 前两个字节fd6c是16位有符号数转为二进制最高位为1即为负值(1111110101101100)，先去掉最高位1(111110101101100)
     * 再把剩下的15位取反(000001010010011)转为10进制是659再加1等于660除以100得到温度是-6.6度,26f2转为10进制是9970除以100得到湿度99.7%，
     * 第五个字节21转为10进制再除以10即电压值为3.3V  该文档作废，用新文档AN-303无线温湿度采集器说明
     *
     * @param data
     * @return
     */
    @Override
    public EquipmentDto<Temperaturehumidity> resolve(String equipmentNumber, String data) {
        EquipmentDto<Temperaturehumidity> equipmentDto = new EquipmentDto();
        byte[] sources = Base64Utils.decodeFromString(data);
        /*String b1ToHex = Strings.padStart(Integer.toHexString(sources[0] & 0xff), 2, '0');
        String b2ToHex = Strings.padStart(Integer.toHexString(sources[1] & 0xff), 2, '0');
        String b3ToHex = Strings.padStart(Integer.toHexString(sources[2] & 0xff), 2, '0');
        String b4ToHex = Strings.padStart(Integer.toHexString(sources[3] & 0xff), 2, '0');
        String b5ToHex = Strings.padStart(Integer.toHexString(sources[4] & 0xff), 2, '0');
        BigDecimal temperature;
        BigDecimal humidity;
        BigDecimal voltage;
        if((sources[0] & 0x80) > 0) { // 负数
            String binary1String = Strings.padStart(Integer.toBinaryString(~sources[0] & 0xff), 8, '0');
            String binary2String = Strings.padStart(Integer.toBinaryString(~sources[1] & 0xff), 8, '0');
            int temperatureInt = Integer.parseInt(binary1String + binary2String, 2);
            temperatureInt += 1;
            temperatureInt *= -1;
            temperature = new BigDecimal(temperatureInt).divide(new BigDecimal("100"));
        } else { // 正数
            temperature = new BigDecimal(Long.parseLong(b1ToHex + b2ToHex, 16)).divide(new BigDecimal("100"));
        }
        humidity = new BigDecimal(Long.parseLong(b3ToHex + b4ToHex, 16)).divide(new BigDecimal("100"));
        voltage = new BigDecimal(Long.parseLong(b5ToHex, 16)).divide(new BigDecimal("10"));*/
        // 温度 有符号
        int b5 = sources[4];
        int b6 = sources[5];
        String binary5 = Strings.padStart(Integer.toBinaryString(b5 & 0xff), 8, '0');
        String binary6 = Strings.padStart(Integer.toBinaryString(b6 & 0xff), 8, '0');
        Short temperatureStr = Short.parseShort(binary5 + binary6, 2);
        BigDecimal temperature = new BigDecimal(temperatureStr / 10);
        // 湿度 无符号
        int b8 = sources[7];
        int b9 = sources[8];
        String binary8 = Strings.padStart(Integer.toBinaryString(b8 & 0xff), 8, '0');
        String binary9 = Strings.padStart(Integer.toBinaryString(b9 & 0xff), 8, '0');
        int humidityInt = Short.toUnsignedInt(Short.parseShort(binary8 + binary9, 2));
        BigDecimal humidity = new BigDecimal(humidityInt / 10);
        // 电压 无符号
        int b10 = sources[9];
        int b11 = sources[10];
        String binary10 = Strings.padStart(Integer.toBinaryString(b10 & 0xff), 8, '0');
        String binary11 = Strings.padStart(Integer.toBinaryString(b11 & 0xff), 8, '0');
        int voltageInt = Short.toUnsignedInt(Short.parseShort(binary10 + binary11, 2));
        BigDecimal voltage = new BigDecimal(voltageInt / 100);
        Temperaturehumidity temperaturehumidity = new Temperaturehumidity();
        temperaturehumidity.setTemperature(temperature);
        temperaturehumidity.setHumidity(humidity);
        temperaturehumidity.setVoltage(voltage);
        temperaturehumidity.setEquipmentid(equipmentNumber);
        temperaturehumidity.setDatastring(data);
        temperaturehumidity.setVoltageState(new BigDecimal(binary11.substring(0, 1)));
        equipmentDto.setEntity(temperaturehumidity);
        return equipmentDto;
    }

    @Override
    public Temperaturehumidity save(Temperaturehumidity equipment, boolean alarmFlag) {
        equipment.setAlarmFlag(alarmFlag);
        temperaturehumidityService.save(equipment);
        return equipment;
    }

    public static void main(String[] args) {
        byte[] sources = Base64Utils.decodeFromString("AQEAAAC3AAJgAWE=");
        // 温度
        int b5 = sources[4];
        int b6 = sources[5];
        String binary5 = Strings.padStart(Integer.toBinaryString(b5 & 0xff), 8, '0');
        String binary6 = Strings.padStart(Integer.toBinaryString(b6 & 0xff), 8, '0');
        Short temperatureStr = Short.parseShort(binary5 + binary6, 2);
        BigDecimal temperature = new BigDecimal(temperatureStr / 10);

        // 湿度
        int b8 = sources[7];
        int b9 = sources[8];
        String binary8 = Strings.padStart(Integer.toBinaryString(b8 & 0xff), 8, '0');
        String binary9 = Strings.padStart(Integer.toBinaryString(b9 & 0xff), 8, '0');
        int humidityInt = Short.toUnsignedInt(Short.parseShort(binary8 + binary9, 2));
        BigDecimal humidity = new BigDecimal(humidityInt / 10);


        // 电压
        int b10 = sources[9];
        int b11 = sources[10];
        String binary10 = Strings.padStart(Integer.toBinaryString(b10 & 0xff), 8, '0');
        String binary11 = Strings.padStart(Integer.toBinaryString(b11 & 0xff), 8, '0');
        int voltageInt = Short.toUnsignedInt(Short.parseShort(binary10 + binary11, 2));
        BigDecimal voltage = new BigDecimal(voltageInt / 100);

        // byte[] sources = Base64Utils.decodeFromString("/Wwm8iE=");
        /*String b1ToHex = Strings.padStart(Integer.toHexString(sources[0] & 0xff), 2, '0');
        String b2ToHex = Strings.padStart(Integer.toHexString(sources[1] & 0xff), 2, '0');
        String b3ToHex = Strings.padStart(Integer.toHexString(sources[2] & 0xff), 2, '0');
        String b4ToHex = Strings.padStart(Integer.toHexString(sources[3] & 0xff), 2, '0');
        String b5ToHex = Strings.padStart(Integer.toHexString(sources[4] & 0xff), 2, '0');
        BigDecimal temperature;
        BigDecimal humidity;
        BigDecimal voltage;
        if((sources[0] & 0x80) > 0) { // 负数
            String binary1String = Strings.padStart(Integer.toBinaryString(~sources[0] & 0xff), 8, '0');
            String binary2String = Strings.padStart(Integer.toBinaryString(~sources[1] & 0xff), 8, '0');
            int temperatureInt = Integer.parseInt(binary1String + binary2String, 2);
            temperatureInt += 1;
            temperatureInt *= -1;
            temperature = new BigDecimal(temperatureInt).divide(new BigDecimal("100"));
        } else { // 正数
            temperature = new BigDecimal(Long.parseLong(b1ToHex + b2ToHex, 16)).divide(new BigDecimal("100"));
        }
        humidity = new BigDecimal(Long.parseLong(b3ToHex + b4ToHex, 16)).divide(new BigDecimal("100"));
        voltage = new BigDecimal(Long.parseLong(b5ToHex, 16)).divide(new BigDecimal("10"));*/
        System.out.println("温度：" + temperature.doubleValue());
        System.out.println("湿度：" + humidity.doubleValue());
        System.out.println("电压：" + voltage.doubleValue());

    }
}
